package com.aube.base.player;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.aube.base.model.VideoHighlightItem;
import com.aube.interact.base.R;
import com.huyn.baseframework.dynamicload.video.ISeekable;
import com.huyn.baseframework.utils.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by hill on 10/24.
 */
public class PlayerSeekBar extends View implements ISeekable {

    private static final String TAG = PlayerSeekBar.class.getSimpleName();

    private int mHighlightColorRed = 0xff663333;
    private int mHighlightColorYellow = 0xffcc9900;
    private int mHighlightColorGray = 0xffcccccc;
    private int mPlayedColor;
    private int mBufferColor = 0xff5f5f5f;
    private int mNormalColor = 0x805f5f5f;
    private Paint mPaint;
    private int mProgress=0;
    private int mBuffer=0;

    private List<Integer> mHighlights;

    private OnSeekChangeListener mOnSeekChangeListener;
    /*初始状态为不可拖动*/
    private boolean mEnabled = false;

    private long mVideoLength=0;

    public PlayerSeekBar(Context context) {
        this(context, null);
    }

    public PlayerSeekBar(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PlayerSeekBar(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);

        mPaint = new Paint();
        mPaint.setAntiAlias(true);

        mPlayedColor = getResources().getColor(R.color.play_progress_color);
    }

    public void enableSeek(boolean enable) {
        this.mEnabled = enable;
        invalidate();
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (mEnabled) {
            this.getParent().requestDisallowInterceptTouchEvent(true);

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    onStartTrackingTouch();
                    updateOnTouch(event);
                    Utils.Log(TAG, "onTouchEvent:DOWN");
                    break;
                case MotionEvent.ACTION_MOVE:
                    updateOnTouch(event);
                    Utils.Log(TAG, "onTouchEvent:DOWN");
                    break;
                case MotionEvent.ACTION_UP:
                    Utils.Log(TAG, "onTouchEvent:UP");
                    if(!jumpToNearestHighlight(event))
                        onStopTrackingTouch();
                    setPressed(false);
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
                case MotionEvent.ACTION_CANCEL:
                    onStopTrackingTouch();
                    setPressed(false);
                    this.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
            }
            return true;
        }
        return false;
    }

    private void updateOnTouch(MotionEvent event) {
        boolean ignoreTouch = ignoreTouch(event.getX(), event.getY());
        if (ignoreTouch) {
            return;
        }
        setPressed(true);

        int width = getWidth();
        int progress = (int) (event.getX() * 100/width);
        onProgressRefresh(progress, true);
    }

    /**
     * 在拖动进度条的情况下，拖动到看点+/-3%处，自动调整到看点
     */
    private boolean jumpToNearestHighlight(MotionEvent event) {
        Utils.Log(TAG, "jumpToNearestHighlight");
        if(mVideoLength > 0 && mHighlights != null && mHighlights.size() > 0) {
            float percent = event.getX()/getWidth();
            for(Integer i : mHighlights) {
                float position = i.intValue() * 1f / mVideoLength;
                if(Math.abs(percent - position) <= 0.03) {
                    Utils.Log(TAG, "jumpToNearestHighlight:" + i.intValue() * 1000);
                    if(mOnSeekChangeListener != null)
                        mOnSeekChangeListener.onLocateProgress(i.intValue() * 1000);
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 在通过滑动屏幕调整进度的情况下，滑动到看点+/-3%处，自动调整到看点
     */
    public int jumpToNearestHighlight(float ratio) {
        if(mVideoLength > 0 && mHighlights != null && mHighlights.size() > 0) {
            for(Integer i : mHighlights) {
                float position = i.intValue() * 1f / mVideoLength;
                if(Math.abs(ratio - position) <= 0.03) {
                    return i.intValue() * 1000;
                }
            }
        }
        return -1;
    }

    private void onStartTrackingTouch() {
        if (mOnSeekChangeListener != null) {
            mOnSeekChangeListener.onStartTrackingTouch(this);
        }
    }

    private void onStopTrackingTouch() {
        Utils.Log(TAG, "onStopTrackingTouch");
        if (mOnSeekChangeListener != null) {
            mOnSeekChangeListener.onStopTrackingTouch(this);
        }
    }

    private boolean ignoreTouch(float xPos, float yPos) {
        boolean ignore = false;
//        float x = xPos - mTranslateX;
//        float y = yPos - mTranslateY;
//
//        float touchRadius = (float) Math.sqrt(((x * x) + (y * y)));
//        if (touchRadius < mTouchIgnoreRadius) {
//            ignore = true;
//        }
        return ignore;
    }

    private void onProgressRefresh(int progress, boolean fromUser) {
        updateProgress(progress, fromUser);
    }

    private void updateProgress(int progress, boolean fromUser) {
        if (progress < 0 || progress > 100) {
            return;
        }

        mProgress = progress;

        if (mOnSeekChangeListener != null) {
            mOnSeekChangeListener.onProgressChanged(this, progress, fromUser);
        }

        invalidate();
    }

    public void setOnSeekChangeListener(OnSeekChangeListener l) {
        mOnSeekChangeListener = l;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        int width = getWidth();
        int height = getHeight();

        int lineHeight = height/4;

        /*画背景条*/
        mPaint.setColor(mNormalColor);
        RectF rectF = new RectF(0, (height-lineHeight)/2, width, (height+lineHeight)/2);
        canvas.drawRoundRect(rectF, lineHeight/2, lineHeight/2, mPaint);

        /*画缓冲条*/
        mPaint.setColor(mBufferColor);
        if(mBuffer >= 99) {
            canvas.drawRoundRect(rectF, lineHeight/2, lineHeight/2, mPaint);
        } else {
            canvas.drawRect(new Rect(lineHeight/2, (height-lineHeight)/2, width*mBuffer/100, (height+lineHeight)/2), mPaint);
        }

        /*画已播放条 */
        mPaint.setColor(mPlayedColor);
        canvas.drawRoundRect(new RectF(0, (height-lineHeight)/2, width*mProgress/100, (height+lineHeight)/2), lineHeight/2, lineHeight/2, mPaint);

        if(mEnabled) {
            /*画highlight点*/
            if (mHighlights != null && mVideoLength > 0) {
                for (Integer i : mHighlights) {
                    int percent = (int) (i.intValue() * 100 / mVideoLength);
                    int point = (int) (width * i.intValue() / mVideoLength);
                    mPaint.setColor(percent > mProgress ? mHighlightColorGray : mHighlightColorYellow);

                    canvas.drawOval(new RectF(point - lineHeight / 2, (height - lineHeight) / 2, point + lineHeight / 2, (height + lineHeight) / 2), mPaint);
                }
            }
        }

        /*画圆点*/
        int progress = width*mProgress/100;
        int startX = progress - height/2;
        int endX = progress + height/2;
        if(startX < 0) {
            startX = 0;
            endX = height;
        }
        if(endX > width) {
            endX = width;
            startX = width - height;
        }
        mPaint.setColor(mPlayedColor);
        canvas.drawOval(new RectF(startX, 0, endX, height), mPaint);
    }

    public void setProgress(int progress) {
        if(progress >= 100)
            progress = 100;
        if(progress <= 0)
            progress = 0;
        if(progress == mProgress)
            return;
        this.mProgress = progress;
        invalidate();
    }

    public int getMax() {
        return 100;
    }

    public int getProgress() {
        return mProgress;
    }

    public void setSecondaryProgress(int buffer) {
        if(buffer >= 100)
            buffer = 100;
        if(buffer <= 0)
            buffer = 0;
        if(buffer == mBuffer)
            return;
        this.mBuffer = buffer;
        invalidate();
    }

    /**
     * @param items
     */
    public void showHighlightPoints(List<VideoHighlightItem> items) {
        if(items == null)
            return;

        mHighlights = new ArrayList<>();
        for(VideoHighlightItem item : items) {
            int time = Integer.parseInt(item.time);
            mHighlights.add(time);
        }

        if(mHighlights.size() > 0)
            invalidate();
    }

    public void setVideoLength(long length) {
        mVideoLength = length;
        invalidate();
    }

    public boolean isVideoLengthEmpty() {
        return mVideoLength <= 0;
    }

    public interface OnSeekChangeListener {
        public void onStopTrackingTouch(PlayerSeekBar seekBar);
        public void onStartTrackingTouch(PlayerSeekBar seekBar);
        public void onProgressChanged(PlayerSeekBar seekBar, int progress, boolean fromUser);
        public void onLocateProgress(int progress);
    }

}
